package com.chat.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.Db;
import com.chat.entry.dto.friend.AddFriendDTO;
import com.chat.entry.enums.MessageType;
import com.chat.entry.po.Friend;
import com.chat.entry.po.User;
import com.chat.entry.po.UserMessage;
import com.chat.entry.po.UserNotes;
import com.chat.entry.vo.friend.FriendListVO;
import com.chat.entry.vo.friend.FriendVO;
import com.chat.mapper.FriendMapper;
import com.chat.mapper.UserMessageMapper;
import com.chat.result.Result;
import com.chat.service.IFriendService;
import com.chat.utils.FirstLetterUtil;
import com.chat.websocket.ChatMessageHandler;
import com.chat.websocket.FriendRequestHandler;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import static com.chat.entry.enums.FriendStatusEnum.AGREED;
import static com.chat.entry.enums.FriendStatusEnum.PENDING;

/**
 * <p>
 * 好友表 服务实现类
 * </p>
 *
 * @author author
 * @since 2025-08-21
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class FriendServiceImpl extends ServiceImpl<FriendMapper, Friend> implements IFriendService {
    private final FriendMapper friendMapper;
    private final UserMessageMapper userMessageMapper;
    private final ChatMessageHandler chatMessageHandler;
    private final FriendRequestHandler friendRequestHandler;

    @Override
    public Result searchFriend(Integer userId, String username) {
//        // 对方的user
//        User user = Db.lambdaQuery(User.class)
//                .eq(User::getUsername, username)
//                .one();
//
//        if (user == null) {
//            return Result.error("用户不存在");
//        }
//
//        Friend friend = friendMapper.selectOne(new LambdaQueryWrapper<Friend>()
//                .and(wrapper -> wrapper
//                        .eq(Friend::getUserId, userId).eq(Friend::getFriendId, user.getUid())
//                        .or()
//                        .eq(Friend::getUserId, user.getUid()).eq(Friend::getFriendId, userId)
//                ));
//
//        // 3. 判断逻辑
//        if (friend != null) {
//            switch (friend.getStatus()) {
//                case PENDING:
//                    // 当前用户uid和发送好友申请的用户uid做判断
//                    if (friend.getUserId().equals(userId)) {
//                        return Result.success("你已发送好友申请，等待对方验证", user);
//                    } else {
//                        return Result.success("对方向你发送了好友请求", user);
//                    }
//                case AGREED:
//                    return Result.success("对方已是你的好友", user);
//                case REFUSED:
//                    return Result.success("好有申请已被拒绝,请重新发送", user);
//            }
//        }
//
//        return Result.success("搜索成功，可以发送好友请求", user);

        // 进行username用户账号的模糊查询

        if (username.length() >= 3) {
            List<User> list = Db.lambdaQuery(User.class)
                    .like(User::getUsername, username)
                    .list();

            list.removeIf(user -> user.getUid().equals(userId));

            return Result.success("搜索成功", list);

        }
        return Result.error("搜索的用户账号至少要有三位才能进行模糊查询");
    }

    @Override
    public Result sendAddFriend(AddFriendDTO addFriendDTO) {
        // 1. 构建好友请求对象
        Friend friend = new Friend();
        friend.setUserId(addFriendDTO.getUserId());
        friend.setFriendId(addFriendDTO.getFriendId());
        friend.setDoGreet(addFriendDTO.getDoGreet());
        friend.setStatus(PENDING);
        friend.setCreataTime(LocalDateTime.now());
        friend.setUpdateTime(LocalDateTime.now());

        // 2. 保存到数据库
        boolean save = save(friend);
        if (!save) {
            return Result.error("请求添加好友失败");
        }

        // 3. 通过 FriendRequestHandler 推送好友请求通知（WebSocket）
        boolean sendFriendRequest = friendRequestHandler.sendFriendRequest(addFriendDTO.getFriendId());
        if (!sendFriendRequest) {
            log.warn("好友请求通知推送失败，receiverId={}", addFriendDTO.getFriendId());
        }

        // 5. 返回成功结果
        return Result.success("请求添加好友成功", null);
    }


    @Override
    public Result agreeFriend(AddFriendDTO addFriendDTO) {
        Friend friend = getOne(new LambdaQueryWrapper<Friend>()
                .eq(Friend::getUserId, addFriendDTO.getFriendId())
                .eq(Friend::getFriendId, addFriendDTO.getUserId())
                .eq(Friend::getStatus, PENDING));

        if (friend == null) {
            return Result.error("好友请求不存在或已处理");
        }

        friend.setStatus(AGREED);
        friend.setUpdateTime(LocalDateTime.now());
        boolean update = updateById(friend);

        if (!update) {
            return Result.error("添加好友失败");
        }

        friendRequestHandler.sendFriendRequest(addFriendDTO.getFriendId());

        UserMessage userMessage = new UserMessage();
        userMessage.setSenderId(friend.getUserId());
        userMessage.setReceiverId(friend.getFriendId());
        userMessage.setType(MessageType.TEXT);
        userMessage.setReadStatus(0);
        userMessage.setContent(friend.getDoGreet());
        userMessage.setSendTime(LocalDateTime.now());

        int insert = userMessageMapper.insert(userMessage);
        if (insert > 0) {
            boolean send = chatMessageHandler.sendTextContent(userMessage);
            if (!send) {
                log.warn("好友请求消息推送失败，receiverId={}", addFriendDTO.getFriendId());
            }
        } else {
            log.warn("好友请求消息入库失败，senderId={}, receiverId={}", addFriendDTO.getUserId(), addFriendDTO.getFriendId());
        }

        return Result.success("添加好友成功", null);
    }

    @Override
    public Result refuseFriend(AddFriendDTO addFriendDTO) {
        Friend friend = getOne(new LambdaQueryWrapper<Friend>()
                .eq(Friend::getUserId, addFriendDTO.getFriendId())
                .eq(Friend::getFriendId, addFriendDTO.getUserId())
                .eq(Friend::getStatus, PENDING));

        if (friend == null) {
            return Result.error("好友申请不存在");
        }

        boolean remove = removeById(friend.getId());

        if (remove) {
            return Result.success("拒绝好友申请成功", null);
        } else {
            return Result.error("拒绝好友申请失败");
        }
    }

    @Override
    public Result queryFriendApplication(Integer uid) {
        List<Friend> friends = list(new LambdaQueryWrapper<Friend>()
                .eq(Friend::getFriendId, uid)
                .eq(Friend::getStatus, PENDING));

        List<User> users = new ArrayList<>();
        for (Friend friend : friends) {
            User user = Db.lambdaQuery(User.class)
                    .eq(User::getUid, friend.getUserId())
                    .one();
            users.add(user);
        }

        return Result.success("查询成功", users);
    }

    @Override
    public Result queryFriend(Integer uid) {
        List<Friend> friends = list(new LambdaQueryWrapper<Friend>()
                .and(wrapper -> wrapper
                        .eq(Friend::getUserId, uid)
                        .or()
                        .eq(Friend::getFriendId, uid))
                .eq(Friend::getStatus, AGREED));

        List<FriendListVO> friendVOList = new ArrayList<>();

        for (Friend friend : friends) {
            FriendListVO friendListVO = new FriendListVO();

            // ✅ 找到对方的 ID
            Integer friendUserId = friend.getUserId().equals(uid)
                    ? friend.getFriendId()
                    : friend.getUserId();

            friendListVO.setUid(friendUserId);

            User user = Db.lambdaQuery(User.class)
                    .eq(User::getUid, friendUserId)
                    .one();

            friendListVO.setAvator(user.getAvator());

            UserNotes userNotes = Db.lambdaQuery(UserNotes.class)
                    .eq(UserNotes::getUserId, uid)
                    .eq(UserNotes::getFriendId, user.getUid())
                    .one();

            friendListVO.setNotes(userNotes != null ? userNotes.getNotes() : user.getNickname());
            friendVOList.add(friendListVO);
        }

        // ✅ 分组
        Map<String, List<FriendListVO>> grouped = friendVOList.stream()
                .collect(Collectors.groupingBy(
                        f -> FirstLetterUtil.getFirstLetter(f.getNotes()),
                        Collectors.toList()
                ));

        // ✅ 排序：字母在前，# 在最后
        Map<String, List<FriendListVO>> sortedGrouped = new TreeMap<>(
                (a, b) -> {
                    if ("#".equals(a)) return 1;   // # 永远在最后
                    if ("#".equals(b)) return -1;
                    return a.compareTo(b);         // 其他按字母顺序
                }
        );
        sortedGrouped.putAll(grouped);

        // ✅ 每组内部再按 notes 排序
        sortedGrouped.forEach((k, v) ->
                v.sort(Comparator.comparing(FriendListVO::getNotes, String.CASE_INSENSITIVE_ORDER))
        );

        return Result.success("查询成功", sortedGrouped);
    }
}
